home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / ISSUE20 / CLINIC / Directio / TSTIO / TSTIO.C next >
Encoding:
C/C++ Source or Header  |  1995-09-11  |  2.3 KB  |  77 lines

  1. /*********************************************************************
  2.  
  3. Author:     Dale Roberts
  4. Date:       8/30/95
  5. Program:    TSTIO.EXE
  6. Compile:    cl -DWIN32 tstio.c
  7.  
  8. Purpose:    Test the GIVEIO device driver by doing some direct
  9.             port I/O.  We access the PC's internal speaker.
  10.  
  11. *********************************************************************/
  12. #include <stdio.h>
  13. #include <windows.h>
  14. #include <math.h>
  15. #include <conio.h>
  16.  
  17. typedef struct {
  18.     short int pitch;
  19.     short int duration;
  20. } NOTE;
  21.  
  22. /*
  23.  *  Table of notes.  Given in half steps.  It's a communication from
  24.  * the "other side."
  25.  */
  26. NOTE notes[] = {{14, 500}, {16, 500}, {12, 500}, {0, 500}, {7, 1000}};
  27.  
  28. /*********************************************************************
  29.   Set PC's speaker frequency in Hz.  The speaker is controlled by an
  30. Intel 8253/8254 timer at I/O port addresses 0x40-0x43.
  31. *********************************************************************/
  32. void setfreq(int hz)
  33. {
  34.     hz = 1193180 / hz;                        // clocked at 1.19MHz
  35.     _outp(0x43, 0xb6);                        // timer 2, square wave
  36.     _outp(0x42, hz);
  37.     _outp(0x42, hz >> 8);
  38. }
  39.  
  40. /*********************************************************************
  41.   Pass a note, in half steps relative to 400 Hz.  The 12 step scale
  42. is an exponential thing.  The speaker control is at port 0x61.
  43. Setting the lowest two bits enables timer 2 of the 8253/8254 timer
  44. and turns on the speaker.
  45. *********************************************************************/
  46. void playnote(NOTE note)
  47. {
  48.     _outp(0x61, _inp(0x61) | 0x03);            // start speaker going
  49.     setfreq((int)(400 * pow(2, note.pitch / 12.0)));
  50.     Sleep(note.duration);
  51.     _outp(0x61, _inp(0x61) & ~0x03);        // stop that racket!
  52. }
  53.  
  54. /*********************************************************************
  55.   Open and close the GIVEIO device.  This should give us direct I/O
  56. access.  Then try it out by playin' our tune.
  57. *********************************************************************/
  58. int main()
  59. {
  60.     int i;
  61.     HANDLE h;
  62.  
  63.     h = CreateFile("\\\\.\\giveio", GENERIC_READ, 0, NULL,
  64.                     OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  65.     if(h == INVALID_HANDLE_VALUE) {
  66.         printf("Couldn't access giveio device\n");
  67.         return -1;
  68.     }
  69.     CloseHandle(h);
  70.  
  71.     for(i=0; i < sizeof(notes)/sizeof(int); ++i)
  72.         playnote(notes[i]);
  73.  
  74.     return 0;
  75. }
  76.  
  77.